import random
import time
from collections import deque


def producer(name, queue, max_items):
    """生产者协程，生成数据并发送给队列"""
    for i in range(max_items):
        item = f"{name}-{i}"
        print(f"生产者 {name} 生产了 {item}")
        time.sleep(random.random() * 0.5)  # 模拟生产时间
        queue.append(item)
        yield  # 暂停，让出控制权


def consumer(name, queue):
    """消费者协程，从队列中消费数据"""
    while True:
        while queue:
            item = queue.popleft()
            print(f"消费者 {name} 消费了 {item}")
            time.sleep(random.random() * 2)  # 模拟消费时间
            yield  # 处理完一个项目后暂停
        yield  # 如果队列为空，也暂停


def scheduler(producers, consumers, max_items):
    """调度器，协调生产者和消费者的执行"""
    producer_done = [False] * len(producers)
    remaining_items = max_items * len(producers)

    # 初始化所有协程
    for p in producers:
        next(p)
    for c in consumers:
        next(c)

    # 主调度循环
    while remaining_items > 0:
        # 随机选择一个生产者
        active_producer_idx = random.randint(0, len(producers) - 1)
        if not producer_done[active_producer_idx]:
            try:
                producers[active_producer_idx].send(None)
            except StopIteration:
                producer_done[active_producer_idx] = True

        # 随机选择一个消费者
        active_consumer_idx = random.randint(0, len(consumers) - 1)
        consumers[active_consumer_idx].send(None)

        # 更新剩余项目计数
        remaining_items = sum(not done for done in producer_done) * max_items


if __name__ == "__main__":
    # 共享队列
    queue = deque()

    # 配置参数
    num_producers = 3
    num_consumers = 2
    items_per_producer = 5

    # 创建生产者和消费者协程
    producers = [
        producer(f"[PRODUCER]-{i}", queue, items_per_producer)
        for i in range(num_producers)
    ]

    consumers = [
        consumer(f"[CONSUMER]-{i}", queue)
        for i in range(num_consumers)
    ]

    # 启动调度器
    scheduler(producers, consumers, items_per_producer)

    print("所有生产消费任务完成!")
